package start.demo01.erupt;

import java.io.BufferedReader;
import java.util.concurrent.*;

import static java.util.concurrent.Executors.newFixedThreadPool;

/**增强的Runable,call()相当于run();包装成线程
 *call()可以有返回值
 *call()可以声明异常
 * Future接口来代表call()方法的返回值，并为Future提供了FutureTask实现类
 * 1。创建一个Callable实现类，包装成线程执行体
 * 2.使用FutureTask来包装Callable对象
 * 3.使用FutureTask实例作为Thread对象的target
 * 4.可以获取线程执行返回值
 *
 *线程池：使用线程池高效执行任务
 * 一个线程再当前任务完成的情况下可以重用
 *Executor
 *  执行线程池中的任务
 *ExecutorService
 * Executor子接口，管理控制任务
 * newCachedThreadPool():创建一个线程池，在必要时创建新的线程，但如果之前的线程可用，先使用之前的线程
 *submit(Callable<T> task)
 * 提交值返回任务以执行，并返回代表任务待处理结果的Future。
 *
 * @author wcj
 */

public class CallableDemo {
    private static int count;
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //test3();
        //创建固定大小的线程池。每次提交一个任务就创建一个线程，直到线程达到线程池的最大大小。
        // 线程池的大小一旦达到最大值就会保持不变，如果某个线程因为执行异常而结束，那么线程池会补充一个新线程
        ExecutorService service=Executors.newFixedThreadPool(3);
        FutureTask<Integer> t0=new FutureTask<>(new Task2());
        FutureTask<Integer> t=new FutureTask<>(new Task());
        service.execute(t0);
        service.execute(t);
        Future<Integer> f=service.submit(new Task());
        System.out.println(t0.get());
        System.out.println(t.get());
        System.out.println(f.get());
    }
    public void test() throws ExecutionException, InterruptedException {
        FutureTask<String> task=new FutureTask<>(()->{
            int i=0;
            for(;i<100;i++);
            return i+"";
        });
        Thread thread=new Thread(task);
        thread.start();
        System.out.println(task.get());
    }

    public static void test2(){
        //Executors.newSingleThreadExecutor();只有一个线程，依次执行
        //Executors.newCachedThreadPool();
        //创建指定数目,一个线程在当前任务完成的情况下可重用
        ExecutorService service= Executors.newFixedThreadPool(3);
        service.execute(()->{
            for(int i=0;i<30;i++)
                System.out.print(i);
        });
        //service.shutdownNow();//立即关闭,并返回正在等待执行的任务列表
        service.shutdown();//关闭执行器，但允许执行完
        //
        //Executors.newCachedThreadPool();
    }

    /*
    * 创建100个线程，往同一个账户添加一块钱
    * */
    public static synchronized  void add(){
        count++;
    }
    public static void test3(){
        for(int i=0;i<100;i++){
            new Thread(()->{
                add();
            }).start();

        }
        System.out.println(count);
    }

    static class Task implements Callable {
        @Override
        public Object call() throws Exception {
            add();
            System.out.println("执行已完成："+count);
            return count;
        }
    }
    static class Task2 implements Callable {
        @Override
        public Object call() throws Exception {
//            BufferedReader
            int i=0;
            System.out.println("快开始睡眠");
            Thread.sleep(1000*1000);
            return count;
        }
    }
}
